package net.sh.dpinfrastructure.config;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;

import com.google.common.collect.Lists;

import net.sh.dpinfrastructure.exception.DPException;
import net.sh.dpinfrastructure.log.DPLogger;

/**
 * {@link net.sh.dpinfrastructure.config.DPConfig}基于文件系统的实现
 * @author Lancer
 * @date 2015年8月2日下午9:08:20 配置文件操作类
 *
 */
public class DPFileConfig implements DPConfig {

    private Properties prop;
    
    private static final DPLogger LOGGER = new DPLogger(DPConfig.class);

    /**
     * 使用{@link java.util.Properties}构造新对象
     * @param prop
     */
    public DPFileConfig(Properties prop) {
        this.prop = prop;
    }
    
    /**
     * 使用指定的配置文件目录构造新对象
     * @param path 配置文件目录
     */
    public DPFileConfig(String path) {
        prop = new Properties();
        try {
             prop.load(new BufferedReader(new InputStreamReader(new FileInputStream(new File(path)))));
        } catch (Exception e) {
            LOGGER.warn("配置文件读取失败", e);
        }
    }
    
    /**
     * 使用启动参数中给定的配置文件地址构造，如果没有指定，默认加载类路径下名为application.properties的配置文件
     */
    public DPFileConfig() {
        prop = new Properties();
        try {
            String configFilePath = System.getProperty("config"); // 指定配置文件路径
            if (!StringUtils.isBlank(configFilePath)) {
                prop.load(new BufferedReader(new InputStreamReader(new FileInputStream(new File(configFilePath)))));
            } else { // 默认从classpath下查找配置文件
                prop.load(new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream("/application.properties"))));
            }
        } catch (IOException e) {
            LOGGER.warn("配置文件读取失败DPFileConfig.java", e);
        }
    }

    @Override
    public boolean containsKey(String key) {
        return prop.containsKey(key);
    }

    /**
     * 
     * Lancer 2015年8月2日下午9:13:07
     * 
     * @param key
     *            参数名
     * @return 参数值
     *
     */
    @Override
    public String get(String key) {
        return prop.getProperty(key);
    }

    @Override
    public String get(String key, String defaultValue) {
        return prop.getProperty(key, defaultValue);
    }

    @Override
    public Set<String> getAllKeys() {
        return prop.stringPropertyNames();
    }

    @Override
    public Boolean getBool(String key) {
        String boolStr = prop.getProperty(key);
        if (StringUtils.isBlank(boolStr)) {
            return null;
        }
        return Boolean.valueOf(boolStr);
    }

    @Override
    public boolean getBoolValue(String key) {
        return Boolean.valueOf(prop.getProperty(key));
    }

    @Override
    public boolean getBoolValue(String key, boolean defaultValue) {
        Boolean bool = getBool(key);
        if (bool == null) {
            return defaultValue;
        }
        return bool.booleanValue();
    }

    @Override
    public Integer getInt(String key) {
        String intStr = prop.getProperty(key);
        try {
            return Integer.parseInt(intStr);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public int getIntValue(String key) {
        Integer integer = getInt(key);
        if (integer == null) {
            throw new DPException("没有对应的int型配置项");
        }
        return integer.intValue();
    }

    @Override
    public int getIntValue(String key, int defaultValue) {
        Integer integer = getInt(key);
        if (integer == null) {
            return defaultValue;
        }
        return integer.intValue();
    }

    @Override
    public List<String> getList(String key, String separator) {
        String realValue = get(key);
        if (StringUtils.isBlank(realValue)) {
            return Lists.newArrayList();
        }
        return Lists.newArrayList(realValue.split(separator));
    };
    
    @Override
    public Long getLong(String key) {
        String longStr = prop.getProperty(key);
        try {
            return Long.parseLong(longStr);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public long getLongValue(String key) {
        Long longObj = getLong(key);
        if (longObj == null) {
            throw new DPException("没有对应的long型配置项");
        }
        return longObj.longValue();
    }

    @Override
    public long getLongValue(String key, long defaultValue) {
        Long longObj = getLong(key);
        if (longObj == null) {
            return defaultValue;
        }
        return longObj.longValue();
    }
    
}
